#ifndef VCCODEC_H_
#define VCCODEC_H_

#include <wx/wx.h>
#include <cv.h>
#include <cvaux.h>
#include "nxColor.h"
#include "cmvision/cmvision.h"
#include "Configuration/RobotIdentification.h"

#include <string> 
#include <list>
#include <vector>
#include <dirent.h>
#include <iostream>

 

using namespace std;
#define CMP_DIF 20


class nxColor;

/** 
 * \brief Contains several methods for image processing.
 * 
 * Due to the use of opencv, libraries for image processing, and wxwidgets, portable library
 * for GUI implementation, there were different image formats to use, incompatible among them.
 * This class contains methods that permit transformation to one format to another, and also 
 * some other methods for color filtering.
 */ 
class vcCodec
{
private:


	

protected:

	double getElapsedSeconds();
	CMVision *mVision;
	bool CMvisionInitialize(int width, int height);
	/*
	 * \brief filter for calibration
	 */
	CvCalibFilter *mCalibFilter;
	
	char* calibFilesPath;
	double *EtalonParams;
	CvCamera* cameraParams;
	bool isCalibEnabled;
	
	CvPoint* imagePoints;
	CvPoint2D32f* realPoints;
	CvMat transMatrix;
	CvMat invTransMatrix;
	double hM[9];
	
		
public:

	/**
	 * \brief Constructor of the class
	 * 
	 * Nothing to be done.
	 */
	vcCodec();
	~vcCodec();
	
	/**
	 * \brief Converts from opencv Image format (IplImage) to wxwidgets format (wxBitmap)
	 * 
	 * This function allows the conversion between this two formats, and also the width and height 
	 * of the output image can be specified, although not necessarly given as parameters.
	 * 
	 * \param *cvImg Pointer to the IplImage to be transformed.
	 * \param oWidth Width of the output image.
	 * \param oHeight Height of the output image.
	 * 
	 * \return wxBitmap format of wxwidgets images.
	 * 
	 */
	wxBitmap cvImg2wxBitmap(IplImage *cvImg,int oWidth=-1,int oHeight=-1); //SI
	
	/**
	 * \brief Defines the ROI (Region of Interest) of an IplImage image format.
	 * 
	 * Selects the area of the image defined by an initial point (init) and the final one (final). Final
	 * must be bigger than init If the init and/or final points are not valid, a NULL pointer will be returned.
	 * 
	 * \param *cvImg Pointer to the IplImage from which the selection will be made.
	 * \param init Initial Point of the selected area.
	 * \param final Final Point of the selected area.
	 * 
	 * \return pointer to the IplImage with the ROI set, or NULL if points were not valid.
	 */
	IplImage* selectImgArea(IplImage *cvImg,CvPoint init,CvPoint final); //SI
	
	
	
	
	
	double calculateFps();
	
	void loadCMVisionColors(nxColor* colorList[],int colorListIndex);
	bool saveCMVisionConf(char *filename);
	void identifyColors(CMVision* mVision, IplImage* imgDst, int colorsNumber, int minArea, int maxArea, bool lensCorrEn);
	void identifyRobots(IplImage* imgDst, RobotIdentification* rid, bool isProyected, bool lensCorrEn);
	void setCalibParams();
	void enableCalib(bool enable);
	double* getEtalonParams();
	void setEtalonParams(double *params);
	list <string> GetFilesInFolder(const char *pFoldername, const char* pPrefix, const char* pSuffix);
	vector <string> getImageFiles ();
	void calibrateCam();
	char* getImgDir();
	void setImgDir(char* dir);
	void erasePoints();
	
	float* getDistParams();
	float* getIntrinsicParams();
	CvMat* getProjectionMatrix();
	CvPoint2D32f TransformPoint(CvPoint point);
	double* getMatrixProyArray();
	bool correctLensDist(CvPoint pointSrc,CvPoint *pointDst);
	bool setPoint(int pointIndex,CvPoint imagePoint,CvPoint2D32f realPoint);
	bool getPoint(int pointIndex, CvPoint* imagePoint, CvPoint2D32f* realPoint);
	
	CvPoint2D32f* getRealPoints();
	CvPoint* getImagePoints();

	/**
	 * Applies a color filter to the IplImage cvImg passed as parameter, and saves the result on the 
	 * IplImage imgMsk. cvImg and imgMsk must have the same dimensions, but cvImg must have three channels,
	 * and imgMsk only one. This is due to the color codification used, which are normally defined for three-
	 * channel images. The destination image is a single-channel one, because only the pixels that are in between
	 * the two thresholds defined, will be painted as white, and the other ones as black.
	 * Color is the vcColor from which the mean and standard deviation values will be
	 * taken into account for filtering. The lowCoef and highCoef are the coeficients used for calculating
	 * the low and high threshold, respectively. See MainFrame for further explanation on the thresholds.
	 * 
	 * \param *cvImg Source image normally of three channels.
	 * \param *imgMsk Destination image, which contains only one channel.
	 * \param *color vcColor used for filtering.
	 * \param colorCode Color Codification to be used, which can be RGB_CODE, HLS_CODE or any other one
	 * defined in vcColor. 
	 * \param lowCoef Low Coeficients for calculating low threshold.
	 * \param highCoef High Coeficients for calculating high threshold.
	 * 
	 */
	//void applyColorFilter(IplImage *cvImg,IplImage* imgMsk, vcColor* color,int colorCode); //NO


    //void applyAllColorsFilter(IplImage *imgSrc,IplImage* imgMsk, IplImage* imgColor, vcColor** colorList,int colorNumber,int colorCode);
    //NO
    //void fillColor(IplImage* imgMsk,IplImage* imgColor,vcColor* color);//NO
	/**
	 * Finds blobs in an already filtered image, imgSrc, which has to be a single-channel image. The destination 
	 * image is also a single-channel one. This functions finds the centre of the blob, and draws a rectangle 
	 * that encloses the blob.
	 * 
	 * \param imgSrc Source image, single-channel one
	 * \param imgDst Destiny image, single-channel one
	 */
	//void findColor(IplImage *imgSrc, IplImage* imgDst,int threshold, int minArea, int maxArea); //NO
	
	/**
	 * \brief Function used to eliminate grayscale pixels, normally presented in background.
	 * 
	 * This function eliminates all the gray pixels of the image, according to the lowGray and highGray thresholds.
	 * The function simply evaluates the pixels of the image in RGB codification. If the channels of the pixels are
	 * too close, then they represent a color in the grayscale. If the gray pixel lies above lowGray and below highgray,
	 * it will be eliminated (i.e. it will be set as a black pixel in RGB code (0,0,0).
	 * 
	 * \param imgSrc Source image
	 * \param imgDst Destiny image
	 * \param lowGray the lower threshold
	 * \param highGray the higuer threshold
	 * \param the color code of the source image. Used to convert images to RGB code.
	 */
	//void removeBckGndGRAY(IplImage *imgSrc,IplImage *imgDst,int lowGray, int highGray,int colorCode=RGB_CODE);
	//NO
	
	//void classifyPixels(IplImage *imgSrc,IplImage *imgDst,vcColor** colorList,int colorCode);
	//NO
	//void calcMDistance(CvMat* );
	//NO
	
	
	
};
#endif /*CODEC_H_*/

